﻿using FastExecutor.ORG.DB;
using FastExecutor.ORG.Entity;
using FastIOC.Annotation;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FastExecutor.Base.Util
{
    [Component]
    public class TaskUtil
    {
        [AutoWired]
        public DB_Task @DB_Task;
        private IScheduler scheduler;
        private IScheduler GetScheduler()
        {
            var properties = new System.Collections.Specialized.NameValueCollection();
            //自定义Plugin 命名空间.类名,程序名称
            properties["quartz.plugin.MyPlugin.type"] = "FastExecutor.ORG.Design.FastSchedulerPlugin,FastExecutor.ORG";
            if (null == scheduler)
            {
                var schedulerFactory = new StdSchedulerFactory(properties);
                scheduler = schedulerFactory.GetScheduler();
            }

            return scheduler;
        }

        public void Init()
        {
            CloseScheduler();
            List<Frame_Task> tasklist = DB_Task.FindAll().Where(a => a.TaskStatus == 1).ToList();
            IScheduler scheduler = GetScheduler();
            foreach (Frame_Task item in tasklist)
            {
                JobDataMap jobData = new JobDataMap();
                jobData.Add("TaskName", item.TaskName);
                jobData.Add("TaskTag", item.TaskTag);
                IJobDetail job = JobBuilder.Create(Type.GetType(item.JobClassName)).SetJobData(jobData).Build();
                ITrigger trigger = GetTrigger(item);
                scheduler.ScheduleJob(job, trigger);

            }
            scheduler.Start();
        }

        public static ITrigger GetTrigger(Frame_Task frame_task)
        {

            TriggerBuilder builder = TriggerBuilder.Create().WithIdentity(frame_task.TaskName, frame_task.TaskTag);
            if (frame_task.TaskExecuteType == 100)
            {
                //如果设置为0，则无间断执行，因为Quartz间隔不能设置为0，这里设置为一毫秒
                if (frame_task.TaskExecutePeriod == 0)
                {
                    TimeSpan span = new TimeSpan(0, 0, 0, 0, 1);
                    builder.WithSimpleSchedule(t =>
                     t.RepeatForever().WithInterval(span));
                }
                else
                {
                    switch (frame_task.TaskExecuteUnit)
                    {
                        case "100":
                            builder.WithSimpleSchedule(t =>
                       t.RepeatForever().WithIntervalInHours(frame_task.TaskExecutePeriod));
                            break;
                        case "200":
                            builder.WithSimpleSchedule(t =>
                      t.RepeatForever().WithIntervalInMinutes(frame_task.TaskExecutePeriod));
                            break;
                        case "300":
                            builder.WithSimpleSchedule(t =>
                      t.RepeatForever().WithIntervalInSeconds(frame_task.TaskExecutePeriod));
                            break;
                    }
                }
            }
            else
            {
                builder.WithCronSchedule(frame_task.CornExplain);
            }

            ITrigger trigger = builder.Build();
            return trigger;
        }

        /// <summary>
        /// 暂停job
        /// </summary>
        /// <param name="frame_task"></param>
        public void PauseJobTask(Frame_Task frame_task)
        {
            IScheduler scheduler = GetScheduler();
            TriggerKey triggerkey = new TriggerKey(frame_task.TaskName, frame_task.TaskTag);
            //暂停job
            scheduler.PauseJob(scheduler.GetTrigger(triggerkey).JobKey);
        }

        /// <summary>
        /// 重启job
        /// </summary>
        /// <param name="frame_task"></param>
        public void ResumeJobTask(Frame_Task frame_task)
        {
            IScheduler scheduler = GetScheduler();
            TriggerKey triggerkey = new TriggerKey(frame_task.TaskName, frame_task.TaskTag);
            //job
            scheduler.ResumeJob(scheduler.GetTrigger(triggerkey).JobKey);
        }

        /// <summary>
        /// 移除job
        /// </summary>
        /// <param name="frame_task"></param>
        public void RemoveTask(Frame_Task frame_task)
        {
            IScheduler scheduler = GetScheduler();
            TriggerKey triggerkey = new TriggerKey(frame_task.TaskName, frame_task.TaskTag);
            //停止job
            scheduler.ResumeJob(scheduler.GetTrigger(triggerkey).JobKey);
            //删除相关的job任务 
            scheduler.DeleteJob(scheduler.GetTrigger(triggerkey).JobKey);

        }
        /// <summary>
        /// 开启任务，包含开启暂停与重启与新增
        /// </summary>
        /// <param name="frame_task"></param>
        public void StartTask(Frame_Task frame_task)
        {
            IScheduler scheduler = GetScheduler();
            TriggerKey triggerkey = new TriggerKey(frame_task.TaskName, frame_task.TaskTag);
            ITrigger trigger = scheduler.GetTrigger(triggerkey);
            if (null != trigger && scheduler.CheckExists(trigger.JobKey))
            {
                //如果有这个job，说明是暂停的任务，重启即可
                ResumeJobTask(frame_task);
            }
            else
            {
                //没有这个job，说明是新增的，或者是停止后开启的
                JobDataMap jobData = new JobDataMap();
                jobData.Add("TaskName", frame_task.TaskName);
                jobData.Add("TaskTag", frame_task.TaskTag);
                IJobDetail job = JobBuilder.Create(Type.GetType(frame_task.JobClassName)).SetJobData(jobData).Build();
                //如果是停止的job，先暂停trigger
                if (scheduler.CheckExists(triggerkey))
                {
                    scheduler.PauseTrigger(triggerkey);
                    scheduler.ScheduleJob(job, trigger);
                    //重启触发器  
                    scheduler.ResumeTrigger(triggerkey);
                }
                else
                {
                    //新增trigger
                    scheduler.PauseTrigger(triggerkey);
                    trigger = GetTrigger(frame_task);
                    scheduler.ScheduleJob(job, trigger);
                }

            }
        }

        public void CloseScheduler()
        {
            IScheduler scheduler = GetScheduler();
            if (scheduler.IsStarted)
            {
                scheduler.PauseAll();
                scheduler.Clear();
                scheduler.Shutdown(true);
            }
        }
    }
}
